package com.xdap.table.service.impl;

import com.xdap.api.constant.ComponentType;
import com.xdap.api.moudle.formconfig.pojo.AssociationField;
import com.xdap.api.moudle.formconfig.pojo.DataSelector;
import com.xdap.api.moudle.formconfig.pojo.FormComponent;
import com.xdap.api.moudle.formconfig.pojo.XdapFormConfig;
import com.xdap.api.moudle.privateapaas.datamodel.pojo.ModelWithFieldVo;
import com.xdap.common.dao.InitFormDao;
import com.xdap.common.utils.ExcelUtil;
import com.xdap.common.utils.FormDataUtil;
import com.xdap.common.utils.InitDateFormatUtil;
import com.xdap.motor.utils.StringUtils;
import com.xdap.table.service.InitTableDetailRelService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class InitTableDetailRelServiceImpl implements InitTableDetailRelService {

    @Autowired
    private InitFormDao initFormDao;

    /**
     * @auth lishushu
     * @2023/6/5 9:05
     * @desc {做单独sheet的页面}
     **/
    @Override
    public String initDetail(String filePath, String formId) {
        if (!filePath.endsWith(".xlsx")) {
            filePath = filePath + "\\低代码业务表关系-单sheet-" + InitDateFormatUtil.getCurrentYyyyMmDdHhMiSs() + ".xlsx";
        }
        // 创建文件对象
        File file = new File(filePath);

        OutputStream fos = null;
        XSSFWorkbook workbook = null;
        try {
            // 如果不存在，或者不是一个文件，直接新建一个响应的对象
            if (!file.exists() || !file.isFile()) {
                file.createNewFile();
            }

            fos = new FileOutputStream(file);
            workbook = new XSSFWorkbook();
            // 
            List<XdapFormConfig> allEnableXdapFormConfig = null;
            if (StringUtils.isBlank(formId)) {
                allEnableXdapFormConfig = initFormDao.getAllEnableXdapFormConfig();
            } else {
                allEnableXdapFormConfig = new ArrayList<>();
                XdapFormConfig xdapFormConfig = initFormDao.getXdapFormConfig(formId);
                allEnableXdapFormConfig.add(xdapFormConfig);
            }
            initSheet(workbook, allEnableXdapFormConfig);


            workbook.write(fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (workbook != null) {
                    workbook.close();
                    log.info("ExcelUtil.java ->> exportExcel() ->> 关闭Workbook资源");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("========================= ExcelUtil.java ->> exportExcel()导出数据到Excel中 ->> 结束 =========================");
        }

        return null;
    }

    private void initSheet(XSSFWorkbook workbook, List<XdapFormConfig> allEnableXdapFormConfig) {
        List<String> rowName = new ArrayList<>();
        rowName.add("页面名称");
        rowName.add("主表名称");
        rowName.add("主表表名");
        rowName.add("从表名称");
        rowName.add("从表表名");
        rowName.add("主表关联页面名称");
        rowName.add("主表关联页面字段");
        rowName.add("从表名称");
        rowName.add("从表被关联的字段名称");


        List<List> dataList = new ArrayList<>();
        dataList.add(rowName);
        // 第一行数据，不需要做
        ExcelUtil.exportExcel(workbook, dataList, "CRM表关系一览", "", 0);

        for (XdapFormConfig xdapFormConfig : allEnableXdapFormConfig) {
            List<ModelWithFieldVo> modelWithFieldVoList = xdapFormConfig.getModelWithFieldVoList();
            String formName = xdapFormConfig.getFormName();
            // 一个页面做一次输入
            dataList = new ArrayList<>();

            // 获取关联表
            List<FormComponent> formComponents = xdapFormConfig.getDetailPage().getFormComponents();
            for (ModelWithFieldVo mw : modelWithFieldVoList) {
                List data = new ArrayList();
                // 命名主子表
                String modelCode = mw.getModelCode();
                String modelName = mw.getModelName();
                Boolean mainModel = mw.getMainModel();
                // 查询所有字段的fc，根据fc获取关联关系
                List<FormComponent> sonFc = FormDataUtil.getChildFc(formComponents);
                sonFc.addAll(formComponents);

                if (mainModel) {
                    // 主表
                    data.add(modelName + "(主)");

                } else {
                    data.add(modelName + "(副)");
                }
                data.add(modelCode);

                List<List> relTablesDetail = getRelTablesDetail(sonFc, modelCode, data,mainModel);
                if (CollectionUtils.isNotEmpty(relTablesDetail)) {
                    dataList.addAll(relTablesDetail);
                }
            }
            ExcelUtil.exportExcel(workbook, dataList, "CRM表关系一览", formName, 1);
        }


    }


    private List<List> getRelTablesDetail(List<FormComponent> formComponents, String modelCode,
                                          List dataSource,Boolean mainModel) {
        List<List> dataList = new ArrayList<>();
        // 数据选择格式
        List<FormComponent> selTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_DATA_SELECTOR.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))

                .collect(Collectors.toList());


        if (CollectionUtils.isNotEmpty(selTables)) {
            for (FormComponent fc : selTables) {
                // 关联的表单
                DataSelector dataSelector = fc.getDataSelector();
                String associationFormId = dataSelector.getOtherFormId();
                // 关联字段
                String originUuid = fc.getUuid();
                String targetUuid =dataSelector.getOtherComponent();
                XdapFormConfig xdapFormConfig = initFormDao.getXdapFormConfig(associationFormId);
                List<FormComponent> assoFormFcs = xdapFormConfig.getDetailPage().getFormComponents();
                List<FormComponent> targetSonFc = FormDataUtil.getChildFc(assoFormFcs);
                targetSonFc.addAll(assoFormFcs);
                List<FormComponent> targetList = assoFormFcs.stream().filter(afc -> afc.getUuid().equals(targetUuid)).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(targetList)) {
                    List<String> data = new ArrayList<>(dataSource);
                    FormComponent formComponent = targetList.get(0);
                    // 获取关联的表信息
                    String modelName = formComponent.getModelName();
                    String targetModelName = formComponent.getModelField();
                    String[] split = targetModelName.split("\\.");
                    data.add(modelName);
                    data.add(split[0]);

                    // 关系名称和关系字段
                    String label = fc.getLabel();
                    data.add(label);
                    FormComponent thisFc = formComponents.stream().filter(thisfc -> thisfc.getUuid().equals(originUuid)).collect(Collectors.toList()).get(0);
                    String thisModelField = thisFc.getModelField();
                    String[] split1 = thisModelField.split("\\.");
                    data.add(split1[1]);

                    String sourceLabel = formComponent.getLabel();
                    data.add("展示文本："+sourceLabel+"-关联字段：id");
                    data.add("展示文本："+split[1]+"-关联字段：id");

                    dataList.add(data);

                }

            }
        }


        // 数据字典格式
        List<FormComponent> dicTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_SELECT_INPUT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(dicTables)) {
            for (FormComponent fc : dicTables) {
                List<String> data = new ArrayList<>(dataSource);
                data.add("数据字典表");
                data.add("apaas_data_dictionary_value");
                String label = fc.getLabel();
                data.add(label);
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("数据字典值code");
                data.add("value_code");
                dataList.add(data);
            }

        }

        // 部门格式
        List<FormComponent> deptTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_DEPARTMENT_SELECT.equals(fc.getComponentType()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(deptTables)) {
            for (FormComponent fc : deptTables) {
                List<String> data = new ArrayList<>(dataSource);
                data.add("部门表");
                data.add("xdap_departments");
                String label = fc.getLabel();
                data.add(label);
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("部门id");
                data.add("id");
                dataList.add(data);
            }
        }




        // 人员格式
        List<FormComponent> usersTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_PEOPLE_SELECT.equals(fc.getComponentType())
                        && (modelCode.equals(fc.getModelCode())||fc.getModelField().startsWith(modelCode+".")))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(usersTables)) {
            for (FormComponent fc : usersTables) {
                List<String> data = new ArrayList<>(dataSource);
                data.add("人员表");
                data.add("xdap_users");
                String label = fc.getLabel();
                data.add(label);
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("人员id");
                data.add("id");

                dataList.add(data);
            }
        }
        // 地址格式
        List<FormComponent> areaTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_WIDGET_AREA.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(areaTables)) {
            for (FormComponent fc : areaTables) {
                List<String> data = new ArrayList<>(dataSource);
                data.add("xdap_province(地址表-xdap_manage_database数据库)");
                data.add("xdap_province");
                String label = fc.getLabel();
                data.add(label);
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("省市区组合成的json");
                data.add("code");

                dataList.add(data);

            }
        }
        // 子表和关联表单不做副表处理
        if(mainModel){
            // 子表格式
            List<FormComponent> sonTables = formComponents.stream()
                    .filter(fc -> ComponentType.FORM_WIDGET_SON_TABLE.equals(fc.getComponentType()))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(sonTables)) {
                for (FormComponent fc : sonTables) {

                    List<String> data = new ArrayList<>(dataSource);

                    String tableName = fc.getLabel();
                    data.add(tableName);
                    String tableModelCode = fc.getTableModelCode();
                    data.add(tableModelCode);
                    data.add("表单id");
                    data.add("document_id");
                    data.add("主表的document_id");
                    data.add("tab_doc_id");
                    dataList.add(data);
                }
            }
            // 关联表单
            List<FormComponent> assoTables = formComponents.stream()
                    .filter(fc -> ComponentType.FORM_ASSOCIATION.equals(fc.getComponentType()))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(assoTables)) {
                for (FormComponent fc : assoTables) {

                    // 关联的表单
                    String associationFormId = fc.getAssociationFormId();
                    AssociationField associationField = fc.getAssociationField();
                    // 关联字段
                    String originUuid = associationField.getOriginUuid();
                    String targetUuid = associationField.getTargetUuid();
                    XdapFormConfig xdapFormConfig = initFormDao.getXdapFormConfig(associationFormId);
                    List<FormComponent> assoFormFcs = xdapFormConfig.getDetailPage().getFormComponents();
                    List<FormComponent> targetSonFc = FormDataUtil.getChildFc(assoFormFcs);
                    targetSonFc.addAll(assoFormFcs);
                    List<FormComponent> targetList = assoFormFcs.stream().filter(afc -> afc.getUuid().equals(targetUuid)).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(targetList)) {
                        List<String> data = new ArrayList<>(dataSource);
                        FormComponent formComponent = targetList.get(0);
                        // 获取关联的表信息
                        String modelName = formComponent.getModelName();
                        String targetModelName = formComponent.getModelField();
                        String[] split = targetModelName.split("\\.");
                        data.add(modelName);
                        data.add(split[0]);

                        // 关系名称和关系字段
                        String label = fc.getLabel();
                        data.add(label);
                        FormComponent thisFc = formComponents.stream().filter(thisfc -> thisfc.getUuid().equals(originUuid)).collect(Collectors.toList()).get(0);
                        String thisModelField = thisFc.getModelField();
                        String[] split1 = thisModelField.split("\\.");
                        data.add(split1[1]);

                        String sourceLabel = formComponent.getLabel();
                        data.add(sourceLabel);
                        data.add(split[1]);
                        dataList.add(data);

                    }


                }
            }
        }



        return dataList;
    }


}
